//基于udp服务器的网络聊天室
#include<unordered_map>
#include"Socket.hpp"
#include"log.hpp"
extern Log lg;
static const uint16_t defaultport=8888;
class UdpServer
{
    public:
    UdpServer(const uint16_t&port=defaultport)
    :port_(port),quit_(true)
    {

    }
    void Init()
    {
    //服务器初始化
    listen_fd.Socket();
    listen_fd.Bind(port_);
    lg(INFO,"Server init success!!");
    }
    bool IsLogIn(const std::string&ip,const uint16_t&port, struct sockaddr_in& client)
    {
        //判断是否正在登陆
        auto iter=User_Login.find(ip);
        if(iter==User_Login.end())
        {
            User_Login.insert({ip,client});
            return false;
        }
        return true;
    }
    void Forward(const std::string& info,const std::string&ip,const uint16_t&port,bool flag)
    {
        if(!flag)
        {
            std::string welcome="欢迎帅哥";
            welcome+="[";
            welcome+=ip;
                welcome+=":";
                welcome+=std::to_string(port);
                welcome+="] 进入直播间！！";
                for(auto &e: User_Login)
                {
                 ssize_t n=   sendto(listen_fd.Fd(),welcome.c_str(),welcome.size(),0,(struct sockaddr*)&(e.second),sizeof(e.second));
                    if(n<0)
                    {
                        lg(DEBUG,"sendto error!!");
                    }
                }
        }
        std::string message="[";
                message+=ip;
                message+=":";
                message+=std::to_string(port);
                message+="]:";
                message+=info;
                std::cout<<"Debug:"<<message<<std::endl;
       for(auto &e:User_Login)
            {
              ssize_t n=  sendto(listen_fd.Fd(),message.c_str(),message.size(),0,(struct sockaddr*)&(e.second),sizeof(e.second));
            if(n<0)
            {
                lg(DEBUG,"sendto error!!");
            }
            }
        
    }
    void Start()
    {
        //服务器运行
        quit_=false;
        char buffer[1024];
        while(!quit_)
        {
            memset(buffer,0,sizeof(buffer));
            //1.读
            struct sockaddr_in peer;
            socklen_t len=sizeof(peer);

           ssize_t n= recvfrom(listen_fd.Fd(),buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);
            if(n<0)
            {
                lg(INFO,"Recvform error!!");
                continue;
            }
            else if(n>0){
                lg(DEBUG,"Recvfrom success!!");
                std::cout<<"Debug："<<buffer<<std::endl;
                //同时获取对方信息
                uint16_t clientport=ntohs(peer.sin_port);
                char ipbuf[64];
                inet_ntop(AF_INET,&peer.sin_addr,ipbuf,sizeof(ipbuf));
                std::string clientip=ipbuf;
                //判断用户登陆
               bool flag= IsLogIn(clientip,clientport,peer);
                //处理转发
                std::string info=buffer;
                Forward(info,clientip,clientport,flag);
                
            }

        }
        quit_=true;
    }
    ~UdpServer()
    {

    }
    private:
    uint16_t port_;
    bool quit_;
    Sock listen_fd;
    std::unordered_map<std::string,struct sockaddr_in> User_Login;
};